"""
智能等待工具模块
提供基于Playwright的智能等待功能，替代固定延时等待
"""

import asyncio
from typing import Optional, List, Tuple, Any


async def wait_for_element(page, selector: str, timeout: int = 5000, state: str = "visible") -> Optional[Any]:
    """
    智能等待元素出现并返回元素对象
    
    Args:
        page: Playwright页面对象
        selector: CSS选择器或文本选择器
        timeout: 超时时间（毫秒）
        state: 元素状态（"visible", "hidden", "attached", "detached"）
    
    Returns:
        元素对象或None
    """
    try:
        element = page.locator(selector).first
        await element.wait_for(state=state, timeout=timeout)
        return element
    except Exception:
        return None


async def wait_for_any_element(page, selectors: List[str], timeout: int = 5000) -> Tuple[Optional[Any], Optional[str]]:
    """
    等待任意一个选择器匹配的元素出现
    
    Args:
        page: Playwright页面对象
        selectors: 选择器列表
        timeout: 总超时时间（毫秒）
    
    Returns:
        (元素对象, 匹配的选择器) 或 (None, None)
    """
    if not selectors:
        return None, None
    
    per_selector_timeout = max(timeout // len(selectors), 1000)  # 每个选择器至少1秒
    
    for selector in selectors:
        try:
            element = page.locator(selector).first
            await element.wait_for(state="visible", timeout=per_selector_timeout)
            return element, selector
        except Exception:
            continue
    return None, None


async def wait_for_all_elements(page, selectors: List[str], timeout: int = 5000) -> List[Optional[Any]]:
    """
    等待所有选择器匹配的元素出现
    
    Args:
        page: Playwright页面对象
        selectors: 选择器列表
        timeout: 超时时间（毫秒）
    
    Returns:
        元素对象列表
    """
    elements = []
    per_selector_timeout = max(timeout // len(selectors), 1000) if selectors else timeout
    
    for selector in selectors:
        try:
            element = page.locator(selector).first
            await element.wait_for(state="visible", timeout=per_selector_timeout)
            elements.append(element)
        except Exception:
            elements.append(None)
    
    return elements


async def smart_wait_for_page_load(page, max_wait: int = 10000) -> bool:
    """
    智能等待页面加载完成
    
    Args:
        page: Playwright页面对象
        max_wait: 最大等待时间（毫秒）
    
    Returns:
        是否加载成功
    """
    try:
        # 先等待DOM加载完成
        await page.wait_for_load_state("domcontentloaded", timeout=max_wait//2)
        # 再等待网络空闲
        await page.wait_for_load_state("networkidle", timeout=max_wait//2)
        return True
    except Exception:
        return False


async def wait_for_network_idle(page, timeout: int = 5000) -> bool:
    """
    等待网络空闲
    
    Args:
        page: Playwright页面对象
        timeout: 超时时间（毫秒）
    
    Returns:
        是否网络空闲
    """
    try:
        await page.wait_for_load_state("networkidle", timeout=timeout)
        return True
    except Exception:
        return False


async def wait_for_text(page, text: str, timeout: int = 5000) -> Optional[Any]:
    """
    等待包含指定文本的元素出现
    
    Args:
        page: Playwright页面对象
        text: 要查找的文本
        timeout: 超时时间（毫秒）
    
    Returns:
        元素对象或None
    """
    try:
        element = page.get_by_text(text).first
        await element.wait_for(state="visible", timeout=timeout)
        return element
    except Exception:
        return None


async def wait_for_clickable(page, selector: str, timeout: int = 5000) -> Optional[Any]:
    """
    等待元素可点击（可见且启用）
    
    Args:
        page: Playwright页面对象
        selector: CSS选择器
        timeout: 超时时间（毫秒）
    
    Returns:
        元素对象或None
    """
    try:
        element = page.locator(selector).first
        await element.wait_for(state="visible", timeout=timeout)
        
        # 检查元素是否启用
        is_enabled = await element.is_enabled()
        if is_enabled:
            return element
        return None
    except Exception:
        return None


async def wait_for_url_change(page, expected_url_part: str, timeout: int = 5000) -> bool:
    """
    等待URL包含指定字符串
    
    Args:
        page: Playwright页面对象
        expected_url_part: 期望的URL包含的字符串
        timeout: 超时时间（毫秒）
    
    Returns:
        是否URL已改变
    """
    try:
        await page.wait_for_url(f"**/{expected_url_part}**", timeout=timeout)
        return True
    except Exception:
        return False